
#if	!defined( __20081116_DEF_WINSOCKINIT_H__ )
#define	__20081116_DEF_WINSOCKINIT_H__

#include	<windows.h>

namespace PCE_Lib {
namespace CEnv_Def {
namespace PCE_Lib_CurrentCEnvironment {
namespace Tools {

class WinSockInit
{
public:
	static bool LoadWinSock( void ) throw()
	{
		WORD	wVersionRequested = MAKEWORD( 2, 2 );	// we want winsock 2.2
		WSADATA	wsaData;

		if( 0 != WSAStartup( wVersionRequested, & wsaData ) ) {
			return false;
		}
		if( (2 != LOBYTE( wsaData.wVersion )) || (2 != HIBYTE( wsaData.wVersion )) ) {
			WSACleanup();
			return false;
		}
		return true;
	}
	static bool UnloadWinSock( void ) throw()
	{
		return 0 == WSACleanup();
	}
protected:
	bool AutoInitWinSock( bool is_init ) throw()
	{
		static int64_t num_ref = 0;

		if( is_init ) {
			++num_ref;
			if( num_ref > 1 ) {
				return true;
			}
			assert( 1 == num_ref );
			return LoadWinSock();
		}else {
			if( num_ref > 1 ) {
				--num_ref;
				return true;
			}
			assert( 1 == num_ref );
			num_ref = 0;
			return UnloadWinSock();
		}
	}
public:
	WinSockInit( void ) throw() { AutoInitWinSock( true ); }
	virtual ~WinSockInit( void ) throw() { AutoInitWinSock( false ); }
};

}	// Tools
}	// PCE_Lib_CurrentCEnvironment
}	// CEnv_Def
}	// PCE_Lib

#endif	// __20081116_DEF_WINSOCKINIT_H__
